package net.m2technologies.open_arm.transaction;

import net.m2technologies.open_arm.utilities.guid.RandomGUID;
import org.opengroup.arm40.transaction.ArmToken;
import org.opengroup.arm40.transaction.ArmTransactionFactory;

/**
 * Copyright 2005 Mark Masterson<br> <br> Licensed under the Apache License, Version 2.0 (the "License");<br> you may
 * not use this file except in compliance with the License.<br> You may obtain a copy of the License at<br> <br>
 * http://www.apache.org/licenses/LICENSE-2.0<br> <br> Unless required by applicable law or agreed to in writing,
 * software<br> distributed under the License is distributed on an "AS IS" BASIS,<br> WITHOUT WARRANTIES OR CONDITIONS
 * OF ANY KIND, either express or implied.<br> See the License for the specific language governing permissions and<br>
 * limitations under the License.<br>
 * <p/>
 * <p>Description: </p>
 *
 * @author Mark Masterson
 * @version 0.010
 */
public abstract class ArmTokenImpl extends ArmInterfaceImpl implements ArmToken {

    private final byte[] bytes;
    private final RandomGUID guid;

    protected ArmTokenImpl(final byte[] bytes, final ArmTransactionFactory creatingFactory) {
        super(creatingFactory);
        this.bytes = bytes;
        this.guid = new RandomGUID(bytes);
    }

    protected ArmTokenImpl(final RandomGUID guid,
                           final ArmTransactionFactory creatingFactory) {
        super(creatingFactory);
        this.guid = guid;
        this.bytes = guid.getValue().getBytes();
    }

    protected RandomGUID getGuid() {
        return guid;
    }

    public boolean copyBytes(final byte[] dest) {
        return copyBytes(dest, 0);
    }

    public boolean copyBytes(final byte[] dest, final int offset) {
        try {
            System.arraycopy(this.bytes, 0, dest, offset, this.bytes.length);
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    public byte[] getBytes() {
        final byte[] defensiveCopy = new byte[getLength()];
        copyBytes(defensiveCopy);
        return defensiveCopy;
    }

    public int getLength() {
        return this.bytes.length;
    }

    public boolean equals(final Object o) {
        if (this == o) return true;
        if (!(o instanceof ArmTokenImpl)) return false;

        final ArmTokenImpl armToken = (ArmTokenImpl) o;

        return guid.equals(armToken.guid);

    }

    public int hashCode() {
        return guid.hashCode();
    }
}
